package com.young.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.benmanes.caffeine.cache.Cache;
import com.young.config.RedisConfig;
import com.young.mapper.UserInfoMapper;
import com.young.pojo.UserInfo;
import com.young.service.UserInfoService;
import com.young.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;

@Slf4j
@Service
@CacheConfig(cacheNames = "caffenieCacheManager")
public class UserInfoServiceImpl implements UserInfoService {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private Redisson redisson;
    @Resource
    private RedisUtil redisUtil;
//    @Resource
//    @Qualifier(value = "caffeineCacheManager")
//    private CacheManager caffeineCacheManager;



    @Override
    @CachePut(key = "#userInfo.id")
    public void addUserInfo(UserInfo userInfo) {
        userInfoMapper.insert(userInfo);
    }

    @Override
    @Cacheable(key = "#id")
    public UserInfo getById(Integer id) {
        log.info("================================");
        log.info("get from redis");
        //先从缓存中获取
        UserInfo userInfo=(UserInfo) redisUtil.get(RedisConfig.USER_CACHE+id);
        if (userInfo!=null){
            //缓存不为空
            return userInfo;
        }
        RLock rLock = redisson.getLock(RedisConfig.USER_LOCK_CACHE + id);
        try{
            rLock.lock();
            //再次从缓存中获取
            userInfo=(UserInfo) redisUtil.get(RedisConfig.USER_CACHE+id);
            if (userInfo!=null){
                return userInfo;
            }
            //缓存为空
            log.info("get from db");
            userInfo = userInfoMapper.selectById(id);
            if (userInfo==null){
                //数据库也为空，设置到redis中，防止缓存穿透
                redisUtil.set(RedisConfig.USER_CACHE+id,null,RedisConfig.LEAST_EXPIRE_TIME);
                return null;
            }
            redisUtil.set(RedisConfig.USER_CACHE+id,userInfo,RedisConfig.EXPIRE_TIME);
        }finally {
            rLock.unlock();
        }
        return userInfo;
    }

    @Override
    @CacheEvict(key = "#userInfo.id")
    public UserInfo updateUserInfo(UserInfo userInfo) {
        log.info("update db");
        UserInfo oldUserInfo=userInfoMapper.selectById(userInfo.getId());
        if (oldUserInfo==null){
            return null;
        }
        int update = userInfoMapper.updateById(userInfo);
        if (update>0){
            redisUtil.remove(RedisConfig.USER_CACHE+userInfo.getId());
        }
        //返回新对象信息
        return userInfo;
    }

    @Override
    @CacheEvict(key = "#id")
    public void deleteById(Integer id) {
        log.info("delete from db");
        int delete = userInfoMapper.deleteById(id);
        if (delete>0){
            redisUtil.remove(RedisConfig.USER_CACHE+id);
        }
    }
}
